/*Author: Seungbeom Ma
 *SJSU 
 * DATE: NOV 16
 * */

package tool.workflow;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;

import tool.core.CoreWork;

import android.util.Log;
// Written by code project , modified by SEUNGBEOM MA
// Date: Oct 30
public class Graph 
{
	public Node rootNode;
	public ArrayList nodes=new ArrayList();
	public int[][] adjMatrix;//Edges will be represented as adjacency Matrix
	private CoreWork cw = new CoreWork();
	int size;
	public void setRootNode(Node n)
	{
		this.rootNode=n;
	}
	
	public Node getRootNode()
	{
		return this.rootNode;
	}
	
	public void addNode(Node n)
	{
		nodes.add(n);
	}
	
	//This method will be called to make connect two nodes
	public void connectNode(Node start,Node end)
	{
		if(adjMatrix==null)
		{
			size=nodes.size();
			adjMatrix=new int[size][size];
		}

		int startIndex=nodes.indexOf(start);
		int endIndex=nodes.indexOf(end);
		adjMatrix[startIndex][endIndex]=1;
		adjMatrix[endIndex][startIndex]=1;
	}
	
	private Node getUnvisitedChildNode(Node n)
	{
		
		int index=nodes.indexOf(n);
		int j=0;
		while(j<size)
		{
			if(adjMatrix[index][j]==1 && ((Node)nodes.get(j)).visited==false)
			{
				return (Node)nodes.get(j);
			}
			j++;
		}
		return null;
	}
	
	//BFS traversal of a tree is performed by the bfs() function
	public ArrayList<String> bfs()
	{
		ArrayList<String> re_al = new ArrayList<String>();

		String str_ids = "";
		String str_tasks = "";
		//BFS uses Queue data structure
		Queue q=new LinkedList();
		q.add(this.rootNode);
		str_tasks = String.valueOf(this.rootNode.get_PROCESS_AMOUNT());
		str_ids = String.valueOf(this.rootNode.get_TASKID());
		re_al.add(str_ids+";"+str_tasks);
		
		printNode(this.rootNode);
		rootNode.visited=true;
		while(!q.isEmpty())
		{
			Node n=(Node)q.remove();
			Node child=null;
			while((child=getUnvisitedChildNode(n))!=null)
			{
				child.visited=true;
				str_tasks = String.valueOf(child.get_PROCESS_AMOUNT());
				str_ids= String.valueOf(child.get_TASKID());
				re_al.add(str_ids+";"+str_tasks);
				printNode(child);
				q.add(child);
			}
		}
		//Clear visited property of nodes
		clearNodes();
		return re_al;
	}
	
	//DFS traversal of a tree is performed by the dfs() function
	public void dfs()
	{
		//DFS uses Stack data structure
		Stack s=new Stack();
		s.push(this.rootNode);
		rootNode.visited=true;
		printNode(rootNode);
		while(!s.isEmpty())
		{
			Node n=(Node)s.peek();
			Node child=getUnvisitedChildNode(n);
			if(child!=null)
			{
				child.visited=true;
				printNode(child);
				s.push(child);
			}
			else
			{
				s.pop();
			}
		}
		//Clear visited property of nodes
		clearNodes();
	}
	
	
	//Utility methods for clearing visited property of node
	private void clearNodes()
	{
		int i=0;
		while(i<size)
		{
			Node n=(Node)nodes.get(i);
			n.visited=false;
			i++;
		}
	}

	//Utility methods for printing the node's label
	private void printNode(Node n)
	{
		System.out.print(n.label+" ");
	}

	
	public String GraphToString(ArrayList<String> P_list){
		String Re_Seq =  "";
		Re_Seq = P_list.get(0);
		for(int i = 1 ; i < P_list.size() ; i++){
			Re_Seq = Re_Seq+":"+ P_list.get(i); 
		}
		
		return Re_Seq;
	}
	
	// Private Algor for project 
	public ArrayList<ArrayList<String>> SJSU_bfs()
	{
		Log.d("GRAPH ", "Running SJSU_bfs");
		Hashtable<String,ArrayList<String>> SJSU_Task_List = new Hashtable<String,ArrayList<String>>();
		ArrayList<String> Local_List = new ArrayList<String>();
		ArrayList<String> Cloud_List1 = new ArrayList<String>();
		ArrayList<String> Cloud_List2 = new ArrayList<String>();
		ArrayList<ArrayList<String>> re_list = new ArrayList<ArrayList<String>>();
		boolean gate = false;
		String str_ids = "";
		String str_tasks = "";
		//BFS uses Queue data structure
		Queue q=new LinkedList();
		q.add(this.rootNode);
		str_tasks = String.valueOf(this.rootNode.get_PROCESS_AMOUNT());
		str_ids = String.valueOf(this.rootNode.get_TASKID());
		if(cw.SJSU_Collection(str_tasks)){
			//System.out.println("Inserting L");
			Local_List.add(str_ids+";"+str_tasks);
		}
		else if(gate == false){
			//System.out.println("Inserting C1");
			Cloud_List1.add(str_ids+";"+str_tasks);
			gate = true;
		}
		else{
			//System.out.println("Inserting c2");
			Cloud_List2.add(str_ids+";"+str_tasks);
			gate = false;
		}
	//	re_al.add(str_ids+";"+str_tasks);
		
		printNode(this.rootNode);
		rootNode.visited=true;
		while(!q.isEmpty())
		{
			Node n=(Node)q.remove();
			Node child=null;
			while((child=getUnvisitedChildNode(n))!=null)
			{
				child.visited=true;
				str_tasks = String.valueOf(child.get_PROCESS_AMOUNT());
				str_ids= String.valueOf(child.get_TASKID());
			//	re_al.add(str_ids+";"+str_tasks);
				if(cw.SJSU_Collection(str_tasks)){
					Local_List.add(str_ids+";"+str_tasks);
				}
				else if(gate == false){
					//System.out.println("Inserting C1");
					Cloud_List1.add(str_ids+";"+str_tasks);
					gate = true;
				}
				else{
					//System.out.println("Inserting c2");
					Cloud_List2.add(str_ids+";"+str_tasks);
					gate = false;
				}
				//printNode(child);
				q.add(child);
			}
		}
		//Clear visited property of nodes
		re_list.add(Local_List);
		re_list.add(Cloud_List1);
		re_list.add(Cloud_List2);
		clearNodes();
		return re_list;
	}
	

}

